package com.eat.fish_service.netty_client.handler;

import com.alibaba.fastjson.JSON;
import com.eat.common_utils.HttpClientUtils;
import com.eat.fish_service.entity.Dao.IpAndPort;
import com.eat.fish_service.entity.Dao.SensorData;
import com.eat.fish_service.netty_client.ManageConnections;
import com.eat.fish_service.netty_client.Message;
import com.eat.fish_service.netty_client.utils.BytesToInt;
import com.eat.fish_service.service.IpAndPortService;
import com.eat.fish_service.service.SensorDataService;
import com.eat.fish_service.utils.GetBeanUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author CZF
 * @create 2022-03-30 1:15
 *
 * 测试用的handler
 */
@Slf4j
public class InHandler extends ChannelInboundHandlerAdapter {

    //从spring容器中取bean
    IpAndPortService ipAndPortService = GetBeanUtils.getBean(IpAndPortService.class);

    //定时任务线程池
    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

    //当通道就绪就会触发该方法
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        Message message = new Message();
//        message.setHead(new byte[]{6,6,6,6});
//        message.setUpdate(new byte[]{1});  //建立连接更新一下数据
//        ctx.writeAndFlush(message);

        //todo 建立连接后，创建一个定时器每十分钟问鱼缸获取一次数据
        //测试用5秒问一次数据，到时候自行改成10分钟
        scheduledThreadPool.scheduleAtFixedRate(new GetSenorDataTask(ctx),0,5, TimeUnit.SECONDS);
    }

    //当通道有读取事件时会触发
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        Message message = (Message) msg;
        String v1 = String.valueOf(BytesToInt.fourBytesToInt(message.getValue1())/100.0);
        String v2 = String.valueOf(BytesToInt.fourBytesToInt(message.getValue2())/100.0);
        String v3 = String.valueOf(BytesToInt.fourBytesToInt(message.getValue3())/100.0);
        String v4 = String.valueOf(BytesToInt.fourBytesToInt(message.getValue4())/100.0);
        String v5 = String.valueOf(BytesToInt.fourBytesToInt(message.getValue5())/100.0);

        //获取当前通道的鱼缸id
        Long aquariumId = ManageConnections.getAquariumId(ctx.channel());

        //传感器数据
        SensorData sensorData = new SensorData();
        sensorData.setAId(aquariumId);
        sensorData.setValue1(v1);
        sensorData.setValue2(v2);
        sensorData.setValue3(v3);
        sensorData.setValue4(v4);
        sensorData.setValue5(v5);

        log.info(sensorData.toString());
        SensorDataService dataService = GetBeanUtils.getBean(SensorDataService.class);
        dataService.getBaseMapper().insert(sensorData);
        //todo 将传感器数据发送给算法接口,需要时放行
//        sendDataToPredictionAlgorithm(sensorData);

    }

    //读取完毕触发
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//        Message message = new Message();
//        message.setHead(new byte[]{6,6,6,6});

    }

    //channel断开连接处理方法
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //根据断开的channel删除map中对应的数据
        for (Long key : ManageConnections.channelList.keySet()) {
            if (ManageConnections.channelList.get(key) == ctx.channel()) {
                //断开连接后，数据库表`ip_and_port`的对应的ip的is_connected改为0

                IpAndPort ipAndPort = new IpAndPort();
                ipAndPort.setAquariumId(key);
                ipAndPort.setIsConnected(0);
                ipAndPortService.updateById(ipAndPort);

                //集合中删除这个通道信息
                ManageConnections.channelList.remove(key);
            }
        }
        super.channelInactive(ctx);
    }

    //异常发生
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        //根据异常的channel删除map中对应的数据
        for (Long key : ManageConnections.channelList.keySet()) {
            if (ManageConnections.channelList.get(key) == ctx.channel()) {
                //断开连接后，数据库表`ip_and_port`的对应的ip的is_connected改为0
                IpAndPort ipAndPort = new IpAndPort();
                ipAndPort.setAquariumId(key);
                ipAndPort.setIsConnected(0);
                ipAndPortService.updateById(ipAndPort);

                //集合中删除这个通道信息
                ManageConnections.channelList.remove(key);
                System.out.println("异常处理执行");

            }
        }
        cause.printStackTrace();
        ctx.close();
    }


    /**
     * 将硬件中获取的每十分钟的一条数据发送给算法接口
     * @param sensorData
     */
    public void sendDataToPredictionAlgorithm(SensorData sensorData){
        log.info(sensorData.toString());

        RestTemplate restTemplate = GetBeanUtils.getBean(RestTemplate.class);
        String url = "http://localhost:xxxxx";
                                    //url,请求数据对象，返回值类型
        String res = restTemplate.postForObject(url, sensorData, String.class);
                            //todo：Object.class是算法返回的结果对象，需自定义，算法只用返回成功/失败，并不需要预测结果
        Object resObj = JSON.parseObject(res, Object.class);


    }
}
